/*
 * @(#)BinaryDefinition.java        1.0 2000/05/09
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */


package xfuzzy.pkg;

/**
 * Definici�n de una operaci�n binaria
 * 
 * @author Francisco Jos� Moreno Velo
 *
 */
public class BinaryDefinition extends Definition {
	
	//----------------------------------------------------------------------------//
	//                           MIEMBROS PRIVADOS                                //
	//----------------------------------------------------------------------------//
	
	/**
	 * Descripci�n de la funci�n en Java
	 */
	private String compute;
	
	/**
	 * Descripci�n de la funci�n en C
	 */
	private String c_compute;
	
	/**
	 * Descripci�n de la funci�n en C++
	 */
	private String cpp_compute;
	
	/**
	 * Descripci�n de la derivada de la funci�n 
	 */
	private String deriv;
	
	//----------------------------------------------------------------------------//
	//                               CONSTRUCTOR                                  //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 * @param pkg Nombre del paquete al que pertenece
	 * @param name Nombre de la funci�n
	 */
	public BinaryDefinition(String pkg, String name) {
		super(pkg, name);
	}
	
	//----------------------------------------------------------------------------//
	//                            M�TODOS P�BLICOS                                //
	//----------------------------------------------------------------------------//
	
	/**
	 * Obtiene el tipo de definici�n
	 */
	public int getKind() {
		return PackageDefinition.BINARY;
	}
	
	/**
	 * Obtiene el c�digo XFL3 de un bloque
	 */
	public String getCode(int kind) {
		switch(kind) {
		case REQUIREMENTS: return super.requires;
		case SOURCE: return super.other;
		case JAVA_EQUAL: return this.compute;
		case C_EQUAL: return this.c_compute;
		case CPP_EQUAL: return this.cpp_compute;
		case DERIV_EQUAL: return this.deriv;
		case UPDATE: return super.update;
		default: return null;
		}
	}
	
	/**
	 * Asigna el c�digo XFL3 de un bloque
	 */
	public void setCode(int kind, String code) {
		switch(kind) {
		case REQUIREMENTS: super.requires = code; break;
		case SOURCE: super.other = code; break;
		case JAVA_EQUAL: this.compute = code; break;
		case C_EQUAL: this.c_compute = code; break;
		case CPP_EQUAL: this.cpp_compute = code; break;
		case DERIV_EQUAL: this.deriv = code; break;
		case UPDATE: this.update = code; break;
		}
	}

	/**
	 * Obtiene la descripci�n XFL3 de la definici�n
	 */
	public String toPkg() {
		String code = "binary "+name+" {"+eol;
		code += super.aliasblock();
		code += super.paramblock();
		code += super.requiresblock();
		if(this.compute != null && this.compute.length() >0)
			code += " java {"+eol+this.compute+eol+"  }"+eol;
		if(this.c_compute != null && this.c_compute.length() >0)
			code += " ansi_c {"+eol+this.c_compute+eol+"  }"+eol;
		if(this.cpp_compute != null && this.cpp_compute.length() >0)
			code += " cplusplus {"+eol+this.cpp_compute+eol+"  }"+eol;
		if(this.deriv != null && this.deriv.length() >0)
			code += " derivative {"+eol+this.deriv+eol+"  }"+eol;
		code += super.updateblock();
		code += super.otherblock();
		code += " }"+eol+eol;
		return code;
	}
	
	//----------------------------------------------------------------------------//
	//                            M�TODOS PRIVADOS                                //
	//----------------------------------------------------------------------------//
	
	/**
	 * Genera el c�digo de la clase
	 */
	protected String class_code() {
		return "public class "+name+" extends Binary {"+eol;
	}
	
	/**
	 * Genera el c�digo de ejecuci�n de la clase
	 */
	protected String compute_code() {
		String code = "";
		if(this.compute != null) {
			code += eol+" public double compute(double a, double b) {"+eol;
			code += variable_code(this.compute);
			code += this.compute+eol;
			code += "  }"+eol;
		}
		if(this.deriv != null) {
			code += eol+" public double[] derivative(double a, double b) {"+eol;
			code += "   double[] deriv = new double[2];"+eol;
			code += variable_code(this.deriv);
			code += this.deriv+eol;
			code += "   return deriv;"+eol;
			code += "  }"+eol;
		}
		return code;
	}
	
	/**
	 * Genera el c�digo del m�todo "getJavaCode" de la clase
	 */
	protected String java_code() {
		String code = eol+" public String getJavaCode() {"+eol;
		code += "   String eol = System.getProperty";
		code += "(\"line.separator\", \"\\n\");"+eol;
		code += "   String code = \"\";"+eol;
		
		String sampled[] = super.sample(compute);
		for(int i=0; i<sampled.length; i++)
			if(sampled[i].trim().length() > 0)
				code += "   code += \"   "+sampled[i]+"\"+eol;"+eol;
		code += "   return code;"+eol;
		code += "  }"+eol;
		return code;
	}
	
	/**
	 * Genera el c�digo del m�todo "getCCode" de la clase
	 */
	protected String c_code() {
		if(c_compute == null || c_compute.length() == 0 ) return super.c_code();
		String code = eol+" public String getCCode() {"+eol;
		code += "   String eol = System.getProperty";
		code += "(\"line.separator\", \"\\n\");"+eol;
		code += "   String code = \"\";"+eol;
		
		String sampled[] = super.sample(c_compute);
		for(int i=0; i<sampled.length; i++)
			if(sampled[i].trim().length() > 0)
				code += "   code += \"   "+sampled[i]+"\"+eol;"+eol;
		code += "   return code;"+eol;
		code += "  }"+eol;
		return code;
	}
	
	/**
	 * Genera el c�digo del m�todo "getCppCode" de la clase
	 */
	protected String cpp_code() {
		if(cpp_compute==null || cpp_compute.length()==0) return super.cpp_code();
		String code = eol+" public String getCppCode() {"+eol;
		code += "   String eol = System.getProperty";
		code += "(\"line.separator\", \"\\n\");"+eol;
		code += "   String code = \"\";"+eol;
		
		String sampled[] = super.sample(cpp_compute);
		for(int i=0; i<sampled.length; i++)
			if(sampled[i].trim().length() > 0)
				code += "   code += \"   "+sampled[i]+"\"+eol;"+eol;
		code += "   return code;"+eol;
		code += "  }"+eol;
		return code;
	}
}
